#include "serialmanager.h"
#include <QTime>
SerialManager::SerialManager(QObject *parent) : QObject(parent)
{

    comPort = new QSerialPort(this);
    timer1 = new QTimer(this);
    rec_total =0;
    btimeStamp = false;
    alignLen =100;
    lenCnt =0;

    connect(this,SIGNAL(signalOpenPort(QString)),this,SLOT(onOpenPort(QString)));
    connect(comPort,SIGNAL(readyRead()),this,SLOT(onReadyRead()));
    connect(timer1,SIGNAL(timeout()),this,SLOT(onTimer1()));
    connect(this,SIGNAL(signalClosePort()),this,SLOT(onClosePort()));
    connect(this,SIGNAL(signalSend(QByteArray)),this,SLOT(onTransmit(QByteArray)));
}
SerialManager::~SerialManager()
{
    delete comPort;
    delete timer1;
}

void SerialManager::onOpenPort(QString name)
{
        qDebug()<<"onOpenPort ThreadID:"<<QThread::currentThreadId();
        QMutexLocker locker(&mutexPort);
        //串口已经打开，但是串口号或者参数有变化,或者串口未打开
       if( comPort->isOpen() && (name != currentPortName))
       {
           qDebug()<<"关闭串口:"+currentPortName;
           comPort->close();
       }

       if(!comPort->isOpen())//串口未打开
       {
           //qDebug()<<"打开串口:"+name;
            comPort->setPortName(name);
         //   comPort->setBaudRate(115200);
            if(!comPort->open(QIODevice::QIODevice::ReadWrite))
            {
                emit error(1,\
                            tr("Can't open %1, error code: %2,infomation:%3")\
                                   .arg(comPort->portName())\
                                   .arg(comPort->error())\
                                   .arg(comPort->errorString()));

                return;
            }
            qDebug()<<"打开串口："<<name;
            comPort->clear();
            currentPortName =  name;
            timer1->start(100); //每5ms发送给主线程显示
       }
}

//设置波特率
void SerialManager::setPortBaudRate(QString param)
{
    QMutexLocker locker(&mutexPort);

    qint32 baud = param.toUInt();

    comPort->setBaudRate(baud);

}

//设置停止位
void SerialManager::setPortStopBits(QSerialPort::StopBits stopBits)
{
    QMutexLocker locker(&mutexPort);
    comPort->setStopBits(QSerialPort::StopBits(stopBits));

}

//设置数据位
void SerialManager::setPortDataBits(QSerialPort::DataBits dataBits)
{
    QMutexLocker locker(&mutexPort);
    comPort->setDataBits(dataBits);

}

//设置校验方式
void SerialManager::setPortParity(QSerialPort::Parity parity)
{
    QMutexLocker locker(&mutexPort);
    comPort->setParity(parity);

}


void SerialManager::onClosePort( )
{
    qDebug()<<"关闭串口:"<<comPort->portName();
    if(comPort->isOpen())
    {
        comPort->close();
        timer1->stop();
    }
}

//读取串口接收到的数据
void SerialManager::onReadyRead()
{
    static quint8 lastByte=0;
    QByteArray data_new =  comPort->readAll();

    QByteArray data_str;
    QByteArray data_hexstr;

    bool isChineseFirstByte= false;

    rec_total+=data_new.size();

    /*清除字符串中的零，以免在转换成字符串是被认为是字符串结束符，
     *造成后面的不能显示
     *
     *送显之前先判断最后一个字节是否为中文字符的高字节，防止中文乱码(只支持BGK)
     * 这是由于中文字符占用两个字节，而qt串口读出来的数据是不确定的，如果只读到了高字节，
     * 转换成unicode之后就会出现乱码
     */

    //上一次处理留下一个字节
    if(lastByte)
    {
        data_str.append(lastByte);
        isChineseFirstByte =true;
        lastByte=0;
    }

    foreach (quint8 byte, data_new) {

        //转换成字符串
        if(byte == 0 || byte == '\r')
        {
            //字符串中剔除
        }else if( (byte == '\n') && btimeStamp){
            //添加时间戳
           QDateTime dateTime = QDateTime::currentDateTime();

          data_str.append(dateTime.toString("[yyyy-MM-dd hh:mm:ss:zzz]\n"));
        }
        else{

            if(!isChineseFirstByte && byte >0x80)
            {//是中文的第一个字节
                isChineseFirstByte = true;
                lastByte = byte;
            }
            else
            {
                isChineseFirstByte =false;
                lastByte =0;
            }
            data_str.append(byte);
        }

        //转换成16进制字符串
        data_hexstr.append( QString("%1").arg(byte,2,16,QChar('0')).toUpper()+" ");
        lenCnt++;
        if(lenCnt>= alignLen)
        {
            if(btimeStamp)
                data_hexstr.append(QDateTime::currentDateTime().toString("[yyyy-MM-dd hh:mm:ss:zzz]\n"));
            else
                data_hexstr.append(QChar('\n'));
            lenCnt=0;
        }


    }
    //最后一个字节是中文的第一字节,则将其删除掉,防止中文乱码
    if(isChineseFirstByte)
    {
        data_str.chop(1);
    }

    QMutexLocker locker(&mutexdata);
    str_to_post.append(data_str);
    hexstr_to_post.append(data_hexstr);


}
void SerialManager::clearData()
{
    QMutexLocker locker(&mutexdata);
    str_to_post.clear();
    hexstr_to_post.clear();
    rec_total = 0;

}

//获取接收总字节数
quint64 SerialManager::getRecCount()
{
    return rec_total;
}


void SerialManager::onTimer1()
{
    QMutexLocker locker(&mutexdata);
    //数据送显
     if(!str_to_post.isEmpty())
     {

         emit update_data(  hexstr_to_post,  str_to_post);
     }
     str_to_post.clear();
     hexstr_to_post.clear();
}

void SerialManager::onTransmit(QByteArray data)
{
    if(comPort->isOpen())
    {
        comPort->write(data);
    }
}

//设置时间戳
void SerialManager::setTimeStamp(bool newState)
{
    btimeStamp = newState;
}

//设置数据对齐
void SerialManager::setAlignment(int len)
{
    alignLen = len;
    lenCnt=0;
}
